python 3.6
¶Mais ne me croyez pas sur parole, on va vérifier
(présentation en avant-deuxième !)
import sys
print(sys.version)
3.6.0b4 (default, Nov 25 2016, 08:08:08) [GCC 5.4.0 20160609]
Bon quoi de neuf, du coup
Vous connaissez déjà la syntaxe suivante
language = "Python"
year = 2016
template = "Bonjour le dernier Meetup %(language)s de l'année %(year)d"
print(template % {"language": language, "year": year})
Bonjour le dernier Meetup Python de l'année 2016
Vous avez peut-être l'habitude d'utiliser
template = "Bonjour le dernier Meetup %s de l'année %d"
print(template % (language, year))
Bonjour le dernier Meetup Python de l'année 2016
Mais c'est long à taper.
Ça c'était en Python 2.
Vous connaissez aussi la nouvelle syntaxe
template = "Bonjour le dernier Meetup {language} de l'année {year}"
print(template.format(language=language, year=year))
Bonjour le dernier Meetup Python de l'année 2016
Mais c'est toujours long à taper...
Et peut-etre même savez-vous que ca permet de faire des choses merveilleuses comme
print("{:~^30}".format(" Bonjour Python ! "))
~~~~~~ Bonjour Python ! ~~~~~~
from datetime import datetime
print("{:%Y-%m-%d}".format(datetime.now()))
2016-11-28
(protip : plongez vous dans les arcanes du .format
sur http://pyformat.info)
f"Bonjour le dernier Meetup {language} de {year}"
'Bonjour le dernier Meetup Python de 2016'
f"Bonjour le dernier Meetup {language} de {datetime.now():%Y}"
'Bonjour le dernier Meetup Python de 2016'
Python, circa 2014 (a.k.a Python 3.4-)
first_grade = 3
grades = [first_grade, 2, 5.7]
class Student:
notes = []
def average(self, multiplier=1):
if not self.grades:
return "Aucune note"
average = sum(self.grades) / len(self.grades)
average *= multiplier
return "Average grade: {:.1f}".format(average)
s = Student()
s.grades = grades
print(s.average())
Average grade: 3.6
Python, circa 2015 (a.k.a Python 3.5)
first_grade = 3
grades = [first_grade, 2, 5.7]
class Student:
notes = []
def average(self, multiplier: float=1) -> str:
if not self.grades:
return "Aucune note"
average = sum(self.grades) / len(self.grades)
average *= multiplier
return "Average grade: {:.1f}".format(average)
s = Student()
s.grades = grades
print(s.average())
Average grade: 3.6
Python, circa 2016 (a.k.a Python 3.6)
from typing import List
first_grade: int = 3
grades: List[float] = [first_grade, 2, 5.7]
class Student:
notes: List[float] = []
def average(self, multiplier: float=1) -> str:
if not self.grades:
return "Aucune note"
average: float = sum(self.grades) / len(self.grades)
average *= multiplier
return f"Average grade: {average:.1f}"
s:Student = Student()
s.grades = grades
print(s.average())
Average grade: 3.6
print(1_000_000_000_000_000)
print(f"{0x_FF_FF_FF_FF:X}")
1000000000000000 FFFFFFFF
Pour l'héritage...
class PluginBase:
subclasses = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
class Plugin1(PluginBase):
pass
class Plugin2(PluginBase):
pass
print(PluginBase.subclasses)
[<class '__main__.Plugin1'>, <class '__main__.Plugin2'>]
... et pour la composition
class IntField:
# this is the new initializer:
def __set_name__(self, owner, name):
self.model = owner
self.name = name
def whats_your_name(self):
print(f"{self.model} m'a nommé {self.name}")
class ModelA:
value_a = IntField()
class ModelB:
value_b = IntField()
ModelA().value_a.whats_your_name()
ModelB().value_b.whats_your_name()
<class '__main__.ModelA'> m'a nommé value_a <class '__main__.ModelB'> m'a nommé value_b
L'API d'asyncio est stabilisée et on peut maintenant créer des générateurs asynchrones
pathlib
amélioré !¶import os, pathlib
path = pathlib.Path() / ".."
print(os.listdir(path))
['Spotify-AdKiller', 'beautifuldjango.github.io', 'agency-jekyll-theme', 'django', 'deps', 'theano', 'test', 'req.txt', 'jupyter']
path = path / "jupyter" / "Python 3.6.ipynb"
print(open(path))
<_io.TextIOWrapper name='../jupyter/Python 3.6.ipynb' mode='r' encoding='UTF-8'>
print(path.parent)
../jupyter
print(path.suffix)
.ipynb
print(path.stem)
Python 3.6
tau
!¶from math import tau, pi, cos, sin
print(tau == 2 * pi)
print(f"{cos(tau):.2f}, {sin(tau):.2f}")
True 1.00, -0.00
Bonus : ils sont plus compacts en mémoire !
list({i: i for i in range(100)}) == list(range(100))
True
secrets
pour générer des clés¶import secrets
print(f"{secrets.randbits(2048):X}")
F68C2A8EB0518742D521FF66DF24E464FC54E2F03BE9C93A2400862907D391BD8A884B22FBCF40E187A3A218A374B178542DD259F1F25C233DD2A0BA33438B775EAAE3EF689CD31249EC36CAB9EFB7E2EDDC2B941F0875123A78FCA7A1C733B62FD77E80740F94809527BF57BFB53774D02DD267D6E4BA812DAFCE2118FF369948FB22E7B60A72546D761D1D35361656C95D7ADF07E79CAE404FA8B9F7A208895EEBE888151B0E702D25A1D9678A6948C739573B1D02534315B6618A92DCDA56AB327B66FD262C125124B8C29042385D6A56894A0B0AB20C9D65F73965CBF33FECFD82B60E46A2190D717F12935E1973322FEB7FF163BB737B5B785AB9F4BA04